
using System;

namespace WindowsFormsApplication1
{


	public class DTW
	{

		private int[] template;
		public DTW (int[] temp)
		{
			defineTemplate(temp);
		}
		
		public int calcularDistancia( int[] amostra)
		{
		
			int [,] DTW = new int[template.Length,amostra.Length];
			int referencia = amostra[amostra.Length/2];
			
			for(int i = 0 ; i < template.Length ; i++)
				DTW[i,0] = 0;
			
			for(int i = 0 ; i < amostra.Length ; i++)
				DTW[0,i] = 0;
			
			int linha0 = amostra[1];
			for(int i = 1 ; i < template.Length ; i++)
				DTW[i,1] = DTW[i-1,1]+custo(template[i],linha0);
			
			int coluna0 = template[1];
			for(int i = 1 ; i < amostra.Length ; i++)
				DTW[1,i] = DTW[1,i-1]+custo(coluna0,amostra[i]-referencia);
			
			for(int i = 1; i < template.Length ; i++)
			{
				for(int j = 1; j < amostra.Length ; j++)
				{
					DTW[i,j]=custo(template[i],amostra[j]-referencia)+ Math.Min(DTW[i-1,j],Math.Min(DTW[i-1,j-1],DTW[i,j-1]));
					                                               
				}
			}
			
				int t = template.Length - 1;
                int a = amostra.Length - 1;
                int k = 1;
                double dist = DTW[t,a];
			
                while (t + a > 2) {
                        if (t == 0) {
                                a--;
                        } else if (a == 0) {
                                t--;
                        } else {
                                double[] steps = {
                                                DTW[t - 1,a - 1], DTW[t - 1,a], DTW[t,a - 1]
                                };
                                double min = Math.Min(steps[0], Math.Min(steps[1], steps[2]));
                                if (min == steps[0]) {
                                        t--;
                                        a--;
                                } else if (min == steps[1]) {
                                        t--;
                                } else if (min == steps[2]) {
                                        a--;
                                }
                        }
                        k++;
                        dist += DTW[t,a];
                }
			dist /= (amostra.Length+template.Length);
			Console.Write(Math.Round(dist).ToString()+"\n");
			if(dist<400)
				defineTemplate(amostra);
			
			amostra = null;
			return (int) dist;
		
		}
		
		private int custo(int t, int l)
		{
			return (t-l)*(t-l);
		}
		
	
		private void defineTemplate(int[] amostra)
		{
			int referencia = amostra[amostra.Length/2];
			
			for(int i = 0 ; i< amostra.Length ; i++)
				amostra[i] = amostra[i] - referencia;
			
			this.template = amostra;
		}
	
	}
}
